package com.ruoyi.flow.service.flowable.impl;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.flow.service.flowable.FlowableProcessInstanceService;
import com.ruoyi.flow.vo.processinstance.StartProcessInstanceVo;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @title:
 * @author: bruce.liu
 * @since: 2024/10/23 16:54
 */
@Slf4j
@Service
@Transactional
public class FlowableProcessInstanceServiceImpl implements FlowableProcessInstanceService {
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RuntimeService runtimeService;

    @Override
    public ProcessInstance startProcessInstance(StartProcessInstanceVo startProcessInstanceVo) {
        ProcessInstanceBuilder processInstanceBuilder = this.runtimeService.createProcessInstanceBuilder();
        if (StringUtils.isNotBlank(startProcessInstanceVo.getProcessDefinitionKey())) {
            processInstanceBuilder.processDefinitionKey(startProcessInstanceVo.getProcessDefinitionKey());
        }
        if (StringUtils.isNotBlank(startProcessInstanceVo.getBusinessKey())) {
            processInstanceBuilder.businessKey(startProcessInstanceVo.getBusinessKey());
        }
        if (MapUtil.isNotEmpty(startProcessInstanceVo.getVariables())) {
            processInstanceBuilder.variables(startProcessInstanceVo.getVariables());
        }
        return processInstanceBuilder.start();
    }

    @Override
    public IPage<ProcessInstance> runPage(IPage<ProcessInstance> page, String processName, String userCode) {
        ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
        if (StringUtils.isNotBlank(processName)) {
            processInstanceQuery.processInstanceNameLike(processName);
        }
        if (StringUtils.isNotBlank(userCode)) {
            processInstanceQuery.startedBy(userCode);
        }
        IPage p = new Page();
        long count = processInstanceQuery.count();
        p.setTotal(count);
        if (count > 0) {
            long firstResult = page.getCurrent() * page.getSize();
            List<ProcessInstance> processInstances = processInstanceQuery.listPage((int) firstResult, (int) page.getSize());
            p.setRecords(processInstances);
        }
        return p;
    }

    @Override
    public IPage<HistoricProcessInstance> hisPage(IPage<HistoricProcessInstance> page, String processName, String userCode) {
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
        if (StringUtils.isNotBlank(processName)) {
            historicProcessInstanceQuery.processInstanceNameLike(processName);
        }
        if (StringUtils.isNotBlank(userCode)) {
            historicProcessInstanceQuery.startedBy(userCode);
        }
        IPage p = new Page();
        long count = historicProcessInstanceQuery.count();
        p.setTotal(count);
        if (count > 0) {
            long firstResult = page.getCurrent() * page.getSize();
            List<HistoricProcessInstance> processInstances = historicProcessInstanceQuery.listPage((int) firstResult, (int) page.getSize());
            p.setRecords(processInstances);
        }
        return p;
    }
}
